package com.idormy.sms.forwarder.workers

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.MediaRecorder
import android.os.Build
import androidx.core.app.ActivityCompat
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.Core
import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.Worker
import com.idormy.sms.forwarder.entity.setting.EmailSetting
import com.idormy.sms.forwarder.utils.sender.EmailUtils
import com.xuexiang.xrouter.utils.TextUtils
import com.xuexiang.xutil.XUtil
import com.xuexiang.xutil.resource.ResUtils.getString
import kotlinx.coroutines.*
import java.io.File
import java.util.Date
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

@Suppress("PrivatePropertyName")
class CallRecordingWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

    companion object {
        private const val TAG = "CallRecordingWorker"
        private const val MAX_RECORDING_DURATION = 1 * 60 * 60 * 1000L // 1小时
        private const val CHECK_INTERVAL = 5000L // 5秒检查一次
        
        // 手动触发录音（用于音频焦点检测）
        fun startRecording(context: Context, phoneNumber: String = "unknown", callType: Int = -1) {
            val data = Data.Builder()
                .putString("action", "start")
                .putString("phoneNumber", phoneNumber)
                .putInt("callType", callType)
                .build()

            val request = OneTimeWorkRequestBuilder<CallRecordingWorker>()
                .setInputData(data)
                .build()

            WorkManager.getInstance(context).enqueue(request)
        }

        fun stopRecording(context: Context) {
            val data = Data.Builder()
                .putString("action", "stop")
                .build()

            val request = OneTimeWorkRequestBuilder<CallRecordingWorker>()
                .setInputData(data)
                .build()

            WorkManager.getInstance(context).enqueue(request)
        }
    }

    private var mediaRecorder: MediaRecorder? = null
    private var isRecording = false
    private var recordingStartTime = 0L
    private var currentRecordingFile: File? = null
    private var recordingJob: Job? = null

    override suspend fun doWork(): Result {
        val action = inputData.getString("action") ?: return Result.failure()
        val phoneNumber = inputData.getString("phoneNumber") ?: ""
        val callType = inputData.getInt("callType", -1)

        Log.d(TAG, "doWork: action=$action, phoneNumber=$phoneNumber, callType=$callType")

        return when (action) {
            "start" -> startRecording(phoneNumber, callType)
            "stop" -> stopRecording()
            else -> Result.failure()
        }
    }

    private suspend fun startRecording(phoneNumber: String, callType: Int): Result {
        if (ActivityCompat.checkSelfPermission(applicationContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            Log.e(TAG, "录音权限未授予")
            return Result.failure()
        }

        try {
            // 获取联系人姓名
            val contacts = PhoneUtils.getContactByNumber(phoneNumber)
            val contactName = if (contacts.isNotEmpty()) contacts[0].name else getString(R.string.unknown_number)

            // 创建录音文件
            val timestamp = System.currentTimeMillis()
            val fileName = "call_${phoneNumber}_${timestamp}.m4a"
            currentRecordingFile = File(applicationContext.cacheDir, fileName)

            // 初始化MediaRecorder
            mediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                MediaRecorder(applicationContext)
            } else {
                @Suppress("DEPRECATION")
                MediaRecorder()
            }

            mediaRecorder?.apply {
                // 根据设置选择音频源
                val audioSource = when (SettingUtils.recordingMode) {
                    1 -> MediaRecorder.AudioSource.MIC  // 仅麦克风
                    2 -> MediaRecorder.AudioSource.VOICE_CALL  // 仅系统音频
                    else -> MediaRecorder.AudioSource.VOICE_COMMUNICATION  // 双向录音
                }
                
                setAudioSource(audioSource)
                setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
                setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
                setAudioEncodingBitRate(SettingUtils.recordingBitRate)
                setAudioSamplingRate(SettingUtils.recordingSampleRate)
                setOutputFile(currentRecordingFile?.absolutePath)

                try {
                    prepare()
                    start()
                    isRecording = true
                    recordingStartTime = System.currentTimeMillis()
                    Log.d(TAG, "录音开始: ${currentRecordingFile?.absolutePath}, 音频源: $audioSource")

                    // 启动定时检查任务
                    startRecordingMonitor(phoneNumber, contactName, callType)

                    return Result.success()
                } catch (e: Exception) {
                    Log.e(TAG, "录音启动失败: ${e.message}")
                    releaseRecorder()
                    return Result.failure()
                }
            }

            return Result.failure()
        } catch (e: Exception) {
            Log.e(TAG, "录音初始化失败: ${e.message}")
            e.printStackTrace()
            releaseRecorder()
            return Result.failure()
        }
    }

    private fun startRecordingMonitor(phoneNumber: String, contactName: String, callType: Int) {
        recordingJob = CoroutineScope(Dispatchers.IO).launch {
            while (isRecording) {
                delay(CHECK_INTERVAL)
                
                val currentTime = System.currentTimeMillis()
                val elapsedTime = currentTime - recordingStartTime

                // 检查是否超过2小时限制
                if (elapsedTime >= MAX_RECORDING_DURATION) {
                    Log.d(TAG, "录音时长超过2小时，准备分段")
                    
                    // 停止当前录音
                    stopRecordingInternal()
                    
                    // 重新开始新的录音
                    withContext(Dispatchers.Main) {
                        startRecording(phoneNumber, callType)
                    }
                }
            }
        }
    }

    private suspend fun stopRecording(): Result {
        return suspendCoroutine { continuation ->
            try {
                stopRecordingInternal()
                
                // 发送录音文件
                currentRecordingFile?.let { file ->
                    if (file.exists() && file.length() > 0) {
                        Log.d(TAG, "录音文件准备发送: ${file.absolutePath}, 大小: ${file.length()} bytes")
                        
                        // 在IO线程中发送邮件
                        CoroutineScope(Dispatchers.IO).launch {
                            try {
                                sendRecordingViaEmail(file, continuation)
                            } catch (e: Exception) {
                                Log.e(TAG, "发送录音文件失败: ${e.message}")
                                file.delete()
                                continuation.resume(Result.failure())
                            }
                        }
                    } else {
                        Log.e(TAG, "录音文件不存在或为空")
                        file.delete()
                        continuation.resume(Result.failure())
                    }
                } ?: run {
                    Log.e(TAG, "录音文件为空")
                    continuation.resume(Result.failure())
                }
            } catch (e: Exception) {
                Log.e(TAG, "停止录音失败: ${e.message}")
                currentRecordingFile?.delete()
                continuation.resume(Result.failure())
            }
        }
    }

    private suspend fun sendRecordingViaEmail(file: File, continuation: kotlin.coroutines.Continuation<Result>) {
        try {
            // 获取所有邮箱发送通道
            val allSenders = Core.sender.getAllNonCache()
            val emailSenders = allSenders.filter { it.type == 1 && it.status == 1 }
            
            if (emailSenders.isEmpty()) {
                Log.e(TAG, "未找到邮箱发送通道")
                file.delete()
                continuation.resume(Result.failure())
                return
            }

            // 使用第一个邮箱发送通道
            val sender = emailSenders[0]
            val emailSetting = Gson().fromJson(sender.jsonSetting, EmailSetting::class.java)
            
            if (emailSetting == null) {
                Log.e(TAG, "邮箱设置解析失败")
                file.delete()
                continuation.resume(Result.failure())
                return
            }

            // 构建消息信息
            val msgInfo = MsgInfo(
                type = "call",
                from = file.name,
                content = "通话录音文件: ${file.name}",
                date = Date(),
                simInfo = "",
                simSlot = -1,
                subId = 0,
                callType = 0
            )

            // 构建规则
            val rule = Rule(
                id = 0,
                type = "call",
                filed = "phone_num",
                check = "is",
                value = "",
                senderList = mutableListOf(sender),
                time = Date(),
                smsTemplate = "",
                senderLogic = "ALL"
            )

            // 发送邮件（带附件）
            EmailUtils.sendMsg(
                setting = emailSetting,
                msgInfo = msgInfo,
                rule = rule,
                senderIndex = 0,
                logId = 0L,
                msgId = 0L
            )

            Log.d(TAG, "录音文件已提交发送")
            // 删除本地文件
            file.delete()
            continuation.resume(Result.success())
        } catch (e: Exception) {
            Log.e(TAG, "发送录音文件异常: ${e.message}")
            e.printStackTrace()
            file.delete()
            continuation.resume(Result.failure())
        }
    }

    private fun stopRecordingInternal() {
        try {
            isRecording = false
            recordingJob?.cancel()
            
            mediaRecorder?.apply {
                stop()
                release()
            }
            mediaRecorder = null
            
            Log.d(TAG, "录音停止")
        } catch (e: Exception) {
            Log.e(TAG, "停止录音异常: ${e.message}")
        }
    }

    private fun releaseRecorder() {
        try {
            isRecording = false
            recordingJob?.cancel()
            
            mediaRecorder?.release()
            mediaRecorder = null
            
            currentRecordingFile = null
        } catch (e: Exception) {
            Log.e(TAG, "释放录音资源异常: ${e.message}")
        }
    }

}